package com.eshipenet.shipnet.commplanrpc.grpc;
import com.eshipenet.shipnet.commplan.FindAllResult;
import com.eshipenet.shipnet.commplan.grpc.*;
import com.eshipenet.shipnet.commplanrpc.service.CommPlanIdGenerator;
import com.eshipenet.shipnet.commplanrpc.service.CommPlanService;
import com.eshipenet.shipnet.commplanrpc.util.GetJObjectUtil;
import com.eshipenet.shipnet.commplanrpc.util.TimestampToDate;
import com.google.protobuf.Struct;
import io.grpc.stub.StreamObserver;
import org.json4s.JsonAST;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.Option;
import scala.collection.immutable.List;
import squirrel.JSONQuery;

import java.util.ArrayList;

public class CommPlanRepoGrpcImpl extends CommPlanRepoGrpc.CommPlanRepoImplBase {
    private Logger              logger = LoggerFactory.getLogger("CommPlanRepoGrpcImpl");
    private CommPlanService     service;
    private CommPlanIdGenerator idGenerator;
    public CommPlanRepoGrpcImpl(CommPlanService service,CommPlanIdGenerator idGenerator) {
        this.service = service;
        this.idGenerator = idGenerator;
    }


    /**
     * 查询列表
     *
     * @param req
     * @param responseObserver
     */
    public void findAll(CommPlanFindAllRequest req, StreamObserver<CommPlanFindAllReply> responseObserver) {

        try {
            logger.info("CommPlanRepoGrpcImpl.findAll.Filter    {}",req.getFilter());
            CommPlanFindAllReply reply = findAllInner(req);
            responseObserver.onNext(reply);
            responseObserver.onCompleted();

        } catch (Exception e) {
            System.out.println(e);
            responseObserver.onError(e);
        }

    }


    /**
     * 创建
     *
     * @param req
     * @param responseObserver
     */
    public void createOne(CommPlanCreateOneRequest req, StreamObserver<CommPlanCreateOneReply> responseObserver) {
        try {
            logger.info("CommPlanRepoGrpcImpl.createOne.data   {}",req.getData());
            CommPlanCreateOneReply reply = createOneInner(req);
            responseObserver.onNext(reply);
            responseObserver.onCompleted();

        } catch (Exception e) {
            responseObserver.onError(e);
        }

    }

    /**
     * 修改
     *
     * @param req
     * @param responseObserver
     */
    public void updateOne(CommPlanUpdateOneRequest req, StreamObserver<CommPlanUpdateOneReply> responseObserver) {
        try {
            logger.info("CommPlanRepoGrpcImpl.updateOne.data   {}",req.getData());
            CommPlanUpdateOneReply reply = updateOneInner(req);
            responseObserver.onNext(reply);
            responseObserver.onCompleted();

        } catch (Exception e) {
            responseObserver.onError(e);
        }

    }


    /**
     * 删除
     *
     * @param req
     * @param responseObserver
     */
    public void deleteOne(CommPlanDeleteOneRequest req, StreamObserver<CommPlanDeleteOneReply> responseObserver) {
        try {
            logger.info("CommPlanRepoGrpcImpl.deleteOne.id  {}",req.getId());
            CommPlanDeleteOneReply reply = deleteOneInner(req);
            responseObserver.onNext(reply);
            responseObserver.onCompleted();

        } catch (Exception e) {
            responseObserver.onError(e);
        }

    }

    public CommPlanFindAllReply findAllInner(CommPlanFindAllRequest req) {

        int limit = req.getFilter().getLimit();
        int offset = req.getFilter().getOffset();

        if (limit == 0) {
            limit = 500;

        }
        if (offset == 0) {
            offset = 1;

        }

        //查询条件
        Struct wheres = req.getFilter().getWhere();

        JsonAST.JObject jObject = GetJObjectUtil.getWhere(wheres);

        //联合查询
        java.util.List<CommPlanFindAllFilterInclude> in_list = req.getFilter().getIncludeList();

        ArrayList<JsonAST.JValue> arrayList = new ArrayList<>();

        for (CommPlanFindAllFilterInclude include : in_list) {

            JsonAST.JValue jValue = new JsonAST.JString(include.getName());

            arrayList.add(jValue);

        }
        List<JsonAST.JValue> includes_list = scala.collection.JavaConverters.asScalaIterator(arrayList.iterator()).toList();

        JsonAST.JArray jArray = new JsonAST.JArray(includes_list);

        //生成查询列表的sql
        JSONQuery jsonQuery = JSONQuery.apply(new JsonAST.JString("CommPlan"),
                                              Option.apply(jObject),
                                              Option.apply(new JsonAST.JString("*")),
                                              Option.apply(jArray),
                                              Option.apply(null),
                                              Option.apply(null));

        FindAllResult result = service.findAll(jsonQuery, limit, offset);
        //数据总数
        int totalCount = result.getTotalCount();
        //列表数据
        java.util.List<CommPlanEdge> list = new ArrayList<>();
        //判断是否有数据，无数据时直接返回
        if (totalCount < 1) {
            //设置分页信息
            PageInfo pageInfo = PageInfo.newBuilder()
                    .setHasNextPage(result.isHasNextPage())
                    .setHasPreviousPage(result.isHasPreviousPage())
                    .build();

            return CommPlanFindAllReply.newBuilder()
                    .setReq(req)
                    .addAllEdges(list)
                    .setPageInfo(pageInfo)
                    .setTotalCount(0).build();
        }

        list = result.getList();

        //设置分页信息
        PageInfo pageInfo = PageInfo.newBuilder()
                .setHasNextPage(result.isHasNextPage())
                .setHasPreviousPage(result.isHasPreviousPage())
                .setStartCursor(result.getStartCursor())
                .setEndCursor(result.getEndCursor()).build();


        return CommPlanFindAllReply.newBuilder()
                .setReq(req)
                .addAllEdges(list)
                .setPageInfo(pageInfo)
                .setTotalCount(totalCount).build();
    }


    public CommPlanCreateOneReply createOneInner(CommPlanCreateOneRequest req) {

        //获取当前时间
        java.sql.Timestamp createdAt = new java.sql.Timestamp(System.currentTimeMillis());

        Struct data = req.getData().getInfo();
        String data_str = GetJObjectUtil.getData(data);
        String key = idGenerator.generate();

      com.eshipenet.shipnet.commplan.CommPlan commPlan =  new com.eshipenet.shipnet.commplan.CommPlan(
        req.getData().getName(),
        req.getData().getDescription(),
        req.getData().getKind(),
        req.getData().getAvatar(),
        req.getData().getQuotaData(),
        req.getData().getQuotaFreq(),
        data_str,
        createdAt,
        createdAt,
        req.getData().getStatus()
      );

      commPlan = service.createOne(key,commPlan);

      CommPlan commPlanBuilder = CommPlan.newBuilder()
                                         .setId(key)
                                         .setName(commPlan.getName())
                                         .setDescription(commPlan.getDescription())
                                         .setKind(commPlan.getKind())
                                         .setAvatar(commPlan.getAvatar())
                                         .setQuotaData(commPlan.getQuotaData())
                                         .setQuotaFreq(commPlan.getQuotaFreq())
                                         .setStatus(commPlan.getStatus())
                                         .setCreatedAt(TimestampToDate.dateTotimestamp(commPlan.getCreatedAt()))
                                         .setUpdatedAt(TimestampToDate.dateTotimestamp(commPlan.getCreatedAt()))
                                         .setInfo(GetJObjectUtil.getData(commPlan.getInfo()))
                                         .build();

        return CommPlanCreateOneReply.newBuilder().setData(commPlanBuilder).setReq(req).build();


    }


    public CommPlanUpdateOneReply updateOneInner(CommPlanUpdateOneRequest req) {
        //获取当前时间
        java.sql.Timestamp updatedAt = new java.sql.Timestamp(System.currentTimeMillis());

        Struct data = req.getData().getInfo();
        String data_str = GetJObjectUtil.getData(data);
        com.eshipenet.shipnet.commplan.CommPlan commPlan = new com.eshipenet.shipnet.commplan.CommPlan(
          req.getData().getName(),
          req.getData().getDescription(),
          req.getData().getKind(),
          req.getData().getAvatar(),
          req.getData().getQuotaData(),
          req.getData().getQuotaFreq(),
          data_str,
          null,
          updatedAt,
          req.getData().getStatus()
        );

      commPlan =  service.updateOne(req.getData().getId(),commPlan);

      CommPlan commPlanBuilder = CommPlan.newBuilder()
                                           .setId(req.getData().getId())
                                           .setName(commPlan.getName())
                                           .setDescription(commPlan.getDescription())
                                           .setKind(commPlan.getKind())
                                           .setAvatar(commPlan.getAvatar())
                                           .setQuotaData(commPlan.getQuotaData())
                                           .setQuotaFreq(commPlan.getQuotaFreq())
                                           .setStatus(commPlan.getStatus())
                                           .setCreatedAt(TimestampToDate.dateTotimestamp(commPlan.getCreatedAt()))
                                           .setUpdatedAt(TimestampToDate.dateTotimestamp(commPlan.getCreatedAt()))
                                           .setInfo(GetJObjectUtil.getData(commPlan.getInfo()))
                                           .build();


        return CommPlanUpdateOneReply.newBuilder().setData(commPlanBuilder).setReq(req).build();


    }



    public CommPlanDeleteOneReply deleteOneInner(CommPlanDeleteOneRequest req) {

        com.eshipenet.shipnet.commplan.CommPlan commPlan = service.deleteOne(req.getId());

        CommPlan commPlanBuilder = CommPlan.newBuilder()
                                           .setId(req.getId())
                                           .setName(commPlan.getName())
                                           .setDescription(commPlan.getDescription())
                                           .setKind(commPlan.getKind())
                                           .setAvatar(commPlan.getAvatar())
                                           .setQuotaData(commPlan.getQuotaData())
                                           .setQuotaFreq(commPlan.getQuotaFreq())
                                           .setStatus(commPlan.getStatus())
                                           .setCreatedAt(TimestampToDate.dateTotimestamp(commPlan.getCreatedAt()))
                                           .setUpdatedAt(TimestampToDate.dateTotimestamp(commPlan.getCreatedAt()))
                                           .setInfo(GetJObjectUtil.getData(commPlan.getInfo()))
                                           .build();


        return CommPlanDeleteOneReply.newBuilder().setData(commPlanBuilder).setReq(req).build();

    }

}

